package log

import (
	_ "embed"
	"errors"
	"fmt"
	"gitee.com/kristas/booting-go/framework/core/configure"
	"reflect"
)

//go:embed layout.yml
var layout []byte

func NewLoggerFactory() LoggerFactoryAdapter {
	return &loggerFactory{}
}

type loggerFactory struct {
	Conf           *Configure
	LoggerAdapters []LoggerAdapter `wire:""`
}

func (f *loggerFactory) GetLogger() (Logger, error) {
	if f.Conf.Style == nil {
		configure.SetConfig(layout)
	}
	err := configure.BindConfiguration(f.Conf)
	if err != nil {
		return nil, err
	}

	var adapter LoggerAdapter
	for _, adp := range f.LoggerAdapters {
		if adp.Bean() == f.Conf.Adapter {
			adapter = adp
		}
	}

	if adapter == nil {
		panic("not found log adapter")
	}

	level, err := parseLevel(f.Conf.Level)
	if err != nil {
		return nil, err
	}

	logger, err := New(adapter, level, f.Conf, DefaultDepth)
	if err != nil {
		return nil, err
	}
	return logger, nil
}

func (f *loggerFactory) GetBeanType() reflect.Type {
	return reflect.TypeOf(new(Logger)).Elem()
}

func parseLevel(level string) (Level, error) {
	levelMapping := map[string]Level{
		"panic": Panic,
		"fatal": Fatal,
		"error": Error,
		"warn":  Warn,
		"info":  Info,
		"debug": Debug,
		"trace": Trace,
	}
	if lvl, ok := levelMapping[level]; ok {
		return lvl, nil
	}
	return 0, errors.New(fmt.Sprintf("log level %s not support (panic,fatal,error,warn,info,debug,trace)", level))
}
